package com.ody.util.code.config;

import com.odianyun.util.io.Closer;
import com.odianyun.util.io.FileUtils;
import com.ody.util.code.Const;
import org.springframework.util.StringUtils;

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.Properties;

public class ConfigGuider {
	private DatabaseConfigPanel dbCfgPanel;
	private VarConfigPanel varCfgPanel;
	private JFrame frame;
	private JLabel statusLine;
	private JTabbedPane tabs;
	private ConfigProperties configProperties;
	private volatile boolean completed;

	public ConfigGuider(ConfigProperties configProperties) throws Exception {
		this.configProperties = configProperties;
		JFrame.setDefaultLookAndFeelDecorated(true);
		frame = new JFrame(Const.CONFIG_GUIDER_TITLE);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		if (System.getProperty("os.name").contains("Window")) {
			UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
		}
		
		Toolkit localToolkit = Toolkit.getDefaultToolkit();
		URL localURL = getClass().getClassLoader().getResource("logo.png");
		frame.setIconImage(localToolkit.createImage(localURL));

		frame.addWindowListener(new WindowAdapter() {
			@Override
			public void windowOpened(WindowEvent e) {
				dbCfgPanel.onWindowOpened();
			}
			@Override
			public void windowClosed(WindowEvent e) {
				dbCfgPanel.onWindowClosed();
			}
		});
	}

	public boolean isCompleted() {
		return completed;
	}

	public Properties getProps() throws Exception {
		Properties props = new Properties();
		props.putAll(varCfgPanel.getConfig());
		props.putAll(dbCfgPanel.getConfig());
		return props;
	}
	
	public void openMainFrame() throws Exception {
		IConfigLog log = new InnerConfigLog();
		
		String themeList = System.getProperty("theme.list");
		if (StringUtils.hasText(themeList)) {
			buildThemeBar(log, StringUtils.tokenizeToStringArray(themeList, ","));
		}

		JPanel root = new JPanel();
		root.setLayout(new BoxLayout(root, BoxLayout.PAGE_AXIS));

		tabs = new JTabbedPane();
		tabs.setBackground(Color.BLUE);
		root.add(tabs);
		
		buildConfigPanel(log);

		JPanel btnPanel = new JPanel();
		btnPanel.setBackground(Color.GREEN);
		
		JButton save = new JButton("保存配置");
		save.setBackground(Color.LIGHT_GRAY);
		save.addActionListener((e) -> {
			OutputStream os = null;
			try {
				String parentPath = FileUtils.getParent(configProperties.getPropertiesPath());
				String saveFileName = FileUtils.getFilename(configProperties.getPropertiesPath());
				if (!saveFileName.startsWith(Const.ME_CONFIG_FILE_PREFIX)) {
					saveFileName = Const.ME_CONFIG_FILE_PREFIX + saveFileName;
				}
				String savePath = new java.io.File(parentPath, saveFileName).getPath();
				Properties props = getProps();
				os = new FileOutputStream(savePath);
				props.store(os, "Saved at " + new java.util.Date() + " by ConfigGuider");
				statusLine.setText("保存成功");
			} catch (Exception ex) {
				statusLine.setText(ex.getMessage());
			} finally {
				Closer.close(os);
			}
		});
		btnPanel.add(save);
		
		JButton confirm = new JButton("确定");
		confirm.setBackground(Color.BLUE);
		confirm.addActionListener((e) -> {
			frame.dispose();
			completed = true;
		});
		btnPanel.add(confirm);
		
		JButton exit = new JButton("退出");
		exit.setBackground(Color.LIGHT_GRAY);
		exit.addActionListener((e) -> {
			System.exit(0);
		});
		btnPanel.add(exit);
		
		root.add(btnPanel);
		
		JPanel status = new JPanel();
		status.setBackground(Color.LIGHT_GRAY);
		JSeparator statusSpt = new JSeparator(1);
		status.add(statusSpt);
		statusLine = new JLabel(" ");
		status.add(statusLine);
		root.add(status);

		frame.add(root);

		frame.pack();
		
		double d1 = Toolkit.getDefaultToolkit().getScreenSize().getWidth();
		double d2 = Toolkit.getDefaultToolkit().getScreenSize().getHeight();
		frame.setLocation((int) (d1 - frame.getWidth()) / 2, (int) (d2 - frame.getHeight()) / 2);
		frame.setVisible(true);
	}
	
	private void rebuildConfigPanel(IConfigLog log) throws Exception {
		tabs.removeAll();
		tabs.updateUI();
		buildConfigPanel(log);
		tabs.updateUI();
		
		frame.pack();
	}
	
	private void buildConfigPanel(IConfigLog log) throws Exception {
        varCfgPanel = new VarConfigPanel(configProperties, log);
        tabs.add("包及路径配置", varCfgPanel);
        
		dbCfgPanel = new DatabaseConfigPanel(configProperties, log);
		tabs.add("数据库配置", dbCfgPanel);
	}
	
	private void buildThemeBar(IConfigLog log, String[] themes) throws Exception {
		JMenuBar menuBar = new JMenuBar();
		JMenu menu = new JMenu("模板切换");
		ButtonGroup group = new ButtonGroup();
		int idx = 0;
		for (String theme : themes) {
			if (idx ++ > 0) {
				menu.addSeparator();
			}
			JRadioButtonMenuItem item = new JRadioButtonMenuItem(theme);
			menu.add(item);
			group.add(item);
			String configuredTheme = configProperties.getProps().getProperty("theme");
			if (theme.equals(configuredTheme)) {
				item.setSelected(true);
			}
			item.addActionListener((e) -> {
				try {
					this.configProperties = ConfigProperties.buildForTheme(theme, false);
					rebuildConfigPanel(log);
				} catch (Exception err) {
					log.write(err.getMessage());
				}
			});
		}
		menuBar.add(menu);
		frame.add(menuBar, BorderLayout.NORTH);
	}

	private class InnerConfigLog implements IConfigLog {
		@Override
		public void write(String log) {
			statusLine.setText(log);
		}
	}

	public static void main(String[] args) throws Exception {
		System.setProperty("theme.list", "ody, oms, simple");

		String theme = Const.THEME;
		ConfigProperties props = ConfigProperties.buildForTheme(theme, true);
		for (String key : props.getObject().stringPropertyNames()) {
			System.out.println(key  + " : " + props.getObject().getProperty(key));
		}
	}
}